import glob
from PIL import Image
import numpy as np
import os
import tifffile  # 用于生成DNG文件
import json

# 设置打印选项（原样保留）
np.set_printoptions(legacy="1.21")

## pattern GRBG
folder_path = r'D:/pkg/Bayer/camera_30/PullNativeData/20250717_113633/camera/nativehaltest/'  # 替换为你的目标路径
keyword = 'OmniTest_Stream1_RAW10_Res2460x2460_Dataspace1_UsageFlag3_Stride3120_Cam0_Frame1.raw'
max_val: int = 2 ** 10 - 1  # 10位RAW的最大值
height: int = 2460
width: int = 2460

# DNG元数据配置 (根据您的传感器调整这些值)
DNG_TAGS = {
    "Make": "OmniVision",  # 传感器制造商
    "Model": "OVXXXX",     # 传感器型号
    "PhotometricInterpretation": 32803,  # CFA格式
    "SamplesPerPixel": 1,                # 单通道
    "BitsPerSample": 16,                 # 16位深度
    "CFARepeatPatternDim": [2, 2],       # CFA矩阵尺寸
    "CFAPattern": [1, 0, 2, 1],          # GRBG模式 (1:G, 0:R, 2:B)，改为整数列表
    "BlackLevel": 0,                     # 黑电平(根据传感器调整)
    "WhiteLevel": [65472],               # 白电平(1023<<6)
    "ColorMatrix1": [0.5, 0, 0, 0, 1, 0, 0, 0, 0.5],  # 示例色彩矩阵
    "DNGVersion": [1, 4, 0, 0],         # DNG 1.4.0.0，改为整数列表
    "DNGBackwardVersion": [1, 1, 0, 0], # 向后兼容版本，改为整数列表
    "Orientation": 1,                    # 正常方向
    "PlanarConfiguration": 1,            # 平面配置
    "Compression": 1,                    # 未压缩
}

fileList = glob.glob(folder_path + keyword)

for filename in fileList:
    print('Processing:', filename)
    
    # 准备输出文件名
    base_name = os.path.splitext(filename)[0]
    outputBMPFilename = base_name + '.bmp'
    outputRAW16Filename = base_name + '-raw16.raw'
    outputTIFFFilename = base_name + '.tiff'
    outputDNGFilename = base_name + '.dng'  # 新增DNG输出文件
    
    # 读取RAW文件
    with open(filename, 'rb') as fp:
        data = np.frombuffer(fp.read(), dtype=np.uint8)
    
    # 计算实际每行字节数
    stride = int(data.shape[0] / height)
    dataMIPI = data.reshape((height, stride))
    
    # 创建10位深度的图像缓冲区
    img_10bit = np.zeros((height, width), dtype=np.uint16)
    
    # 计算有效列数（每行实际数据字节数）
    colEnd = int(width * 1.25)
    
    # MIPI RAW10解包（GRBG格式）
    # 使用位运算正确解包10位数据
    img_10bit[:, 0::4] = (dataMIPI[:, 0:colEnd:5].astype(np.uint16) << 2) | (dataMIPI[:, 4:colEnd:5] & 0x03)
    img_10bit[:, 1::4] = (dataMIPI[:, 1:colEnd:5].astype(np.uint16) << 2) | ((dataMIPI[:, 4:colEnd:5] & 0x0c) >> 2)
    img_10bit[:, 2::4] = (dataMIPI[:, 2:colEnd:5].astype(np.uint16) << 2) | ((dataMIPI[:, 4:colEnd:5] & 0x30) >> 4)
    img_10bit[:, 3::4] = (dataMIPI[:, 3:colEnd:5].astype(np.uint16) << 2) | ((dataMIPI[:, 4:colEnd:5] & 0xc0) >> 6)
    
    # ========================================================================
    # 生成16位RAW数据（将10位数据左移6位）
    # ========================================================================
    img_16bit = (img_10bit << 6).astype(np.uint16)
    
    # 保存RAW16文件（无文件头的纯像素数据）
    with open(outputRAW16Filename, 'wb') as fp:
        fp.write(img_16bit.tobytes())
    print("Saved RAW16:", outputRAW16Filename)
    
    # ========================================================================
    # 生成16位TIFF文件
    # ========================================================================
    # 使用PIL的"I;16"模式创建16位灰度图像
    tiff_img = Image.fromarray(img_16bit, mode='I;16')
    tiff_img.save(outputTIFFFilename)
    print("Saved TIFF:", outputTIFFFilename)
    
    # ========================================================================
    # 新增：生成DNG文件（带元数据的RAW）
    # ========================================================================
    # 使用tifffile库创建包含DNG元数据的文件
    tifffile.imwrite(
        outputDNGFilename,
        img_16bit,
        photometric='cfa',  # 指定为CFA格式
        metadata=DNG_TAGS,
        byteorder='<',      # 小端字节序(IBM PC)
        compression=None    # 无压缩
    )
    print("Saved DNG:", outputDNGFilename)
    
    # ========================================================================
    # 生成8位BMP文件（保留原始功能）
    # ========================================================================
    # 将10位数据归一化到0-255范围
    img_8bit = (img_10bit / max_val * 255).clip(0, 255).astype(np.uint8)
    bmp_img = Image.fromarray(img_8bit)
    bmp_img.save(outputBMPFilename)
    print("Saved BMP:", outputBMPFilename)

print("All conversions completed!")